from configure.db_configure import db
from common import db_utils
from datetime import datetime
from datetime import timedelta
from service.info import info_service
import json
import logging
import action.ws as ws

CREATE_SQL='''
    CREATE TABLE IF NOT EXISTS t_task
    (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    deviceName    VARCHAR(128)  NOT NULL DEFAULT "",
    state   INT NOT NULL, -- 0 删除  1 运行中 2 挂起 3 完成 4 失败
    stateText   VARCHAR(32)  NOT NULL DEFAULT "",
    nextRuntime    DATETIME , -- 挂起后的下次运行时间
    step   INT NOT NULL     DEFAULT 0,
    stepText   VARCHAR(32)     NOT NULL DEFAULT "",
    infoContents   TEXT     NOT NULL DEFAULT "[]", 
    createTime     DATETIME     NOT NULL,
    updateTime     DATETIME     NOT NULL
    );
    '''

CREATE_SQL_HISTORY='''
    CREATE TABLE IF NOT EXISTS t_task_history
    (
    id INT PRIMARY KEY,
    deviceName    VARCHAR(128)  NOT NULL DEFAULT "",
    state   INT NOT NULL, -- 0 删除  1 运行中 2 挂起 3 完成 4 失败
    stateText   VARCHAR(32)     NOT NULL DEFAULT "",
    step   INT NOT NULL     DEFAULT 0,
    stepText   VARCHAR(32)     NOT NULL DEFAULT "",
    nextRuntime    DATETIME , -- 挂起后的下次运行时间
    infoContents   TEXT     NOT NULL DEFAULT "[]", 
    createTime     DATETIME     NOT NULL,
    updateTime     DATETIME     NOT NULL
    );
    '''

class CONS():
    STATE_DELETE:int=0
    STATE_RUNNING:int=1
    STATE_SUSPEND:int=2
    STATE_COMPLETE:int=3
    STATE_FAULT:int=4


def countTask(deviceName) -> int:
    with db() as session :
        return session.findOne("select count(1) as num from t_task where deviceName=?",(deviceName,))

def findSuspendTask(deviceName):
    with db() as session :
        return session.findList2("select * from t_task where deviceName=? and state = ? and nextRuntime < ? limit 10",(deviceName,CONS.STATE_SUSPEND,datetime.now()))

def findRunningTask(deviceName):
    with db() as session :
        return session.findList2("select * from t_task where deviceName=? and state = ? limit 10",(deviceName,CONS.STATE_RUNNING))

def createTask(deviceName):
    logging.info("%s 启动任务" %(deviceName,))
    now = datetime.now()
    with db() as session :
        task = session.insertEntity("t_task",{
            "deviceName" : deviceName,
            "state" : CONS.STATE_RUNNING,
            "stateText" : "",
            "createTime":now,
            "updateTime":now,
        })
        ws.emit("task")
        return task

def completeTask(taskId,recordInfoContentList:list=[],msg:str=""):
    logging.info("%s 完成任务" %(taskId,))
    now = datetime.now()
    with db() as session :
        task = session.findOne2("select * from t_task where id=?",(taskId,))
        if task!=None:
            session.deleteById("t_task",taskId)
            task["updateTime"]=now
            task["state"]=CONS.STATE_COMPLETE
            task["stateText"]=msg
            task["step"]=0
            task["stepText"]=""
            task["nextRuntime"]=None
            infoContentList:list = json.loads(task["infoContents"])
            infoContentList.extend(recordInfoContentList)
            task["infoContents"]=json.dumps(infoContentList, ensure_ascii=False)
            session.insertEntity("t_task_history",task)
            ws.emit("task")

def faultTask(taskId,recordInfoContentList:list=[],msg:str=""):
    logging.warning("%s 失败任务" %(taskId,))
    now = datetime.now()
    with db() as session :
        task = session.findOne2("select * from t_task where id=?",(taskId,))
        if task!=None:
            session.deleteById("t_task",taskId)
            task["updateTime"]=now
            task["state"]=CONS.STATE_FAULT
            task["stateText"]=msg
            infoContentList:list = json.loads(task["infoContents"])
            infoContentList.extend(recordInfoContentList)
            task["infoContents"]=json.dumps(infoContentList, ensure_ascii=False)
            session.insertEntity("t_task_history",task)
            ws.emit("task")

def suspendTask(taskId,step,sleepSec:int,recordInfoContentList:list=[],msg:str=""):
    logging.info("%s 挂起任务 %s" %(taskId,step))
    now = datetime.now()
    with db() as session :
        task = session.findOne2("select * from t_task where id=?",(taskId,))
        if task!=None:
            nextRuntime = now + timedelta(seconds=sleepSec)
            task["updateTime"]=now
            task["state"]=CONS.STATE_SUSPEND
            task["step"]=step
            task["stepText"]=msg
            task["nextRuntime"]=nextRuntime
            infoContentList:list = json.loads(task["infoContents"])
            infoContentList.extend(recordInfoContentList)
            task["infoContents"]=json.dumps(infoContentList, ensure_ascii=False)
            session.updateEntity("t_task",task)
            ws.emit("task")


def activateTask(taskId):
    logging.info("%s 激活任务" %(taskId))
    now = datetime.now()
    with db() as session :
        task = session.findOne2("select * from t_task where id=?",(taskId,))
        if task!=None:
            task["updateTime"]=now
            task["state"]=CONS.STATE_RUNNING
            task["nextRuntime"]=None
            session.updateEntity("t_task",task)
            ws.emit("task")



def findPage(deviceName,pageNum:int,pageSize:int):
    offsize = db_utils.limitStart(pageNum,pageSize)
    with db() as session:
        total = session.findOne("select count(*) as num from t_task where deviceName=? ", (deviceName,))
        items = session.findList2("select * from t_task where deviceName=? order by id desc limit ?,?",(deviceName,offsize,pageSize) )
        return {
            "total":total,
            "items":items
        }
        

def findPageHistory(deviceName,pageNum:int,pageSize:int):
    offsize = db_utils.limitStart(pageNum,pageSize)
    with db() as session:
        total = session.findOne("select count(*) as num from t_task_history where deviceName=? ", (deviceName,))
        items = session.findList2("select * from t_task_history where deviceName=? order by id desc limit ?,?",(deviceName,offsize,pageSize) )
        return {
            "total":total,
            "items":items
        }
